package com.gitee.wsl.common.ui.ext

import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Canvas
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.ColorMatrix
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.decodeToImageBitmap
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection

expect fun ImageBitmap.toByteArray(): ByteArray?

fun ImageBitmap.getPixel(x: Int, y: Int): Color {
    if (x < 0 || x >= width || y < 0 || y >= height) {
        return Color.Transparent
    }
    val buffer = IntArray(1)
    readPixels(buffer, x, y, 1, 1)
    return Color(buffer[0])
}

expect fun ImageBitmap.Companion.fromBytes(bytes: ByteArray) : ImageBitmap

expect fun ImageBitmap.Companion.fromPixmap(
    width : Int, height : Int, colors : IntArray
) : ImageBitmap

fun ImageBitmap.resize(w : Int, h : Int) : ImageBitmap {
    if (width == w && h == h){
        return this
    }
    val bitmap = ImageBitmap(w, h)

    Canvas(bitmap).apply {
        drawImageRect(
            image = this@resize,
            dstSize = IntSize(w, h),
            paint = Paint()
        )
    }

    return bitmap
}

fun ImageBitmap.scaleToWidthCompose(scaleWidth: Int): ImageBitmap {
    if (scaleWidth <= 0 || width == scaleWidth) return this
    val scale = scaleWidth.toFloat() / width
    val targetHeight = maxOf((height * scale).toInt(), 1)
    val output = ImageBitmap(scaleWidth, targetHeight)
    val old = this.toByteArray()?.decodeToImageBitmap()?:return this

    Canvas(output).let { canvas ->
        CanvasDrawScope().draw(
            canvas = canvas,
            size   = Size(scaleWidth.toFloat(), targetHeight.toFloat()),
            density = Density(1f, 1f),
            layoutDirection = LayoutDirection.Ltr
        ) {
            drawImage(
                image     = old,
                srcOffset = IntOffset.Zero,
                srcSize   = IntSize(width, height),
                dstOffset = IntOffset.Zero,
                dstSize   = IntSize(scaleWidth, targetHeight),
                colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) })
            )
        }
    }

    return output
}